#include <bits/stdc++.h>

#define eb emplace_back
#define fi first
#define se second
#define in read<int>()
#define rep(i, x, y) for(int i = (x); i <= (y); i++)
#define per(i, x, y) for(int i = (x); i >= (y); i--)

using namespace std;

using ll = long long;
using pii = pair < int, int >;
using vec = vector < int >;
using veg = vector < pii >;

template < typename T > T read() {
	T x = 0; bool f = 0; char ch = getchar();
	while(!isdigit(ch)) f |= ch == '-', ch = getchar();
	while(isdigit(ch)) x = x * 10 + (ch ^ 48), ch = getchar();
	return f ? -x : x;
}

const int N = 1e5 + 10;

int dfn[N], siz[N], fa[N], R, m, n, ind[N], top[N], son[N], attack[N], rt[N], dep[N], tim;
vec G[N];

namespace seg {
	const int N = 1e7 + 10;
	int ch[N][2], val[N], ndn;
	void upd(int &x, int pos, int l = 1, int r = n) {
		int y = ++ndn; val[y] = val[x] + 1; ch[y][0] = ch[x][0]; ch[y][1] = ch[x][1]; x = y; if(l == r) return; int mid = l + r >> 1;
		if(pos <= mid) upd(ch[x][0], pos, l, mid); else upd(ch[x][1], pos, mid + 1, r);
	}
	int qkth(int x, int y, int &k, int tp, int l, int r) {
		if(k > r - l + 1 - val[y] + val[x]) return k -= r - l + 1 - val[y] + val[x], -1; if(l == r) return l;
		int mid = l + r >> 1, ans = tp == 0 ? qkth(ch[x][0], ch[y][0], k, tp, l, mid) : qkth(ch[x][1], ch[y][1], k, tp, mid + 1, r);
		if(ans == -1) ans = tp == 0 ? qkth(ch[x][1], ch[y][1], k, tp, mid + 1, r) : qkth(ch[x][0], ch[y][0], k, tp, l, mid);
		return ans;
	}
	int query(int x, int y, int xl, int xr, int &k, int tp, int l = 1, int r = n) {
		//	cerr << xl << " " << xr << endl;
		if(xl == l && xr == r) return qkth(x, y, k, tp, l, r); int mid = l + r >> 1;
		if(xr <= mid) return query(ch[x][0], ch[y][0], xl, xr, k, tp, l, mid);
		else if(xl > mid) return query(ch[x][1], ch[y][1], xl, xr, k, tp, mid + 1, r);
		else {
			if(tp == 1) {
				int ans = query(ch[x][1], ch[y][1], mid + 1, xr, k, tp, mid + 1, r);
				if(ans == -1) ans = query(ch[x][0], ch[y][0], xl, mid, k, tp, l, mid);
				return ans;
			} else {
				int ans = query(ch[x][0], ch[y][0], xl, mid, k, tp, l, mid);
				if(ans == -1) ans = query(ch[x][1], ch[y][1], mid + 1, xr, k, tp, mid + 1, r);
				return ans;
			}
		}
	}
}

void dfs(int x, int p) { dep[x] = dep[p] + 1; siz[x] = 1; for(auto y : G[x]) dfs(y, x), siz[x] += siz[y], son[x] = siz[y] > siz[son[x]] ? y : son[x]; }
void dfs1(int x, int anc) { top[x] = anc; ind[dfn[x] = ++tim] = x; if(son[x]) dfs1(son[x], anc); for(auto y : G[x]) if(y ^ son[x]) dfs1(y, y); }
int query(int x, int y, int fr, int cur, int k) {
	if(attack[x] <= fr) k++;
	int ans = -1; veg pot;
	while(top[x] ^ top[y]) {
		if(dep[top[x]] < dep[top[y]]) pot.eb(dfn[top[y]], dfn[y]), y = fa[top[y]];
		else ans = seg :: query(rt[fr], rt[cur], dfn[top[x]], dfn[x], k, 1), x = fa[top[x]];
		if(ans != -1) return ind[ans];
	} int tp = 0; if(dfn[x] > dfn[y]) swap(x, y), tp ^= 1; ans = seg :: query(rt[fr], rt[cur], dfn[x], dfn[y], k, tp);
	if(ans != -1) return ind[ans]; reverse(pot.begin(), pot.end());
	for(auto v : pot) { ans = seg :: query(rt[fr], rt[cur], v.fi, v.se, k, 0); if(ans != -1) return ind[ans]; }
	return ans;
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("1.in", "r", stdin);
#endif
	n = in; rep(i, 1, n) fa[i] = in, (fa[i] == 0 ? (R = i, void()) : G[fa[i]].eb(i));
	dfs(R, 0); dfs1(R, R); m = in; int ans = 0;
	rep(i, 1, m) {
		int tp = in, a = in, b, k, y; rt[i] = rt[i - 1];
		if(tp == 1) seg :: upd(rt[i], dfn[a]), attack[a] = i;
		else b = in, k = in, y = in, ans = query(a, b, y, i, k), (ans = ans == b ? -1 : ans), printf("%d\n", ans);
	}
	return 0;
}
